﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;

namespace BF
{
    public class AES : IDisposable
    {
        private RijndaelManaged _rm;
        private ICryptoTransform _encryptTrans;
        private ICryptoTransform _decryptTrans;


        public AES(string key, string iv, CipherMode cipher = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
            : this(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(iv), cipher, padding)
        {

        }


        public AES(byte[] key, byte[] iv, CipherMode cipher = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
        {
            _rm = new RijndaelManaged
            {
                Key = key,
                IV = iv,
                Mode = cipher,
                Padding = padding,
            };
            _encryptTrans = _rm.CreateEncryptor();
            _decryptTrans = _rm.CreateDecryptor();
        }


        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="toEncrypt">需要加密的字符串</param>
        /// <returns>加密后的base64字符串</returns>
        public string Encrypt(string toEncrypt)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(toEncrypt);
            byte[] result = _encryptTrans.TransformFinalBlock(bytes, 0, bytes.Length);
            return Convert.ToBase64String(result);
        }

        /// <summary>
        /// 加密
        /// </summary>
        public byte[] Encrypt(byte[] toEncrypt)
        {
            byte[] result = _encryptTrans.TransformFinalBlock(toEncrypt, 0, toEncrypt.Length);
            return result;
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="base64StrToDecrypt">需要解密的base64字符串</param>
        public string Decrypt(string base64StrToDecrypt)
        {
            byte[] bytes = Convert.FromBase64String(base64StrToDecrypt);
            byte[] result = _decryptTrans.TransformFinalBlock(bytes, 0, bytes.Length);
            return Encoding.UTF8.GetString(result);
        }

        /// <summary>
        /// 解密
        /// </summary>
        public byte[] Decrypt(byte[] toDecrypt)
        {
            byte[] result = _decryptTrans.TransformFinalBlock(toDecrypt, 0, toDecrypt.Length);
            return result;
        }

        public void Dispose()
        {
            _encryptTrans.Dispose();
            _decryptTrans.Dispose();
            _rm.Dispose();

            _encryptTrans = null;
            _decryptTrans = null;
            _rm = null;
        }
    }
}